﻿using DevTrends.MvcDonutCaching;
using MPic.Business.BLL;
using MPic.Business.Entity;
using MPic.Business.Enums;
using MPic.Common;
using MPic.Filters;
using MPic.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace MPic.Controllers
{
    [RoutePrefix("main")]
    public class MainController : BaseController
    {
        [ExcUserAuth]
        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <returns></returns>
        [ExcUserAuth]
        public ActionResult Login()
        {
            return View();
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="email"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        [HttpPost, ExcUserAuth]
        public ActionResult Login(string email, string password)
        {
            #region MyRegion

            try
            {
                if (string.IsNullOrEmpty(email))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("登录邮箱为空.");
                }
                if (string.IsNullOrEmpty(password))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("登录密码为空.");
                }
                var user = UsersBLL.Instance.GetUser(email.Trim(), EncryptHelper.MD5(password.Trim()));
                if (user == null)
                {
                    srm.code = ErrorCode.LoginFail.ToInt();
                    throw new InvalidOperationException("登录邮箱或密码有误.");
                }
                if (!user.IsEnable)
                {
                    srm.code = ErrorCode.LoginFail.ToInt();
                    throw new InvalidOperationException("你的账号已禁用.");
                }
                //票证过期时间
                var expiraTime = DateTime.Now.Add(FormsAuthentication.Timeout);
                //登录成功写Cookie
                var ticket = new FormsAuthenticationTicket(
                    1,
                    user.UserName,
                    DateTime.Now,
                    expiraTime,
                    false,
                    $"{user.UserId};{user.UserName}"
                    );
                var cookie = new HttpCookie(
                    FormsAuthentication.FormsCookieName,
                    FormsAuthentication.Encrypt(ticket));
                cookie.HttpOnly = true; //不能通过客户端脚本访问cookie
                cookie.Expires = expiraTime;
                Response.Cookies.Add(cookie);
            }
            catch (InvalidOperationException e)
            {
                srm.msg = e.Message;
            }
            catch (Exception e)
            {
                srm.code = ErrorCode.BusySystem.ToInt();
                srm.msg = ErrorCode.BusySystem.Description();
                LoggerHelper.Log("【Main】->【Login】", e);
            }
            return Result(srm);
            #endregion
        }

        /// <summary>
        /// 注册
        /// </summary>
        /// <returns></returns>
        [ExcUserAuth]
        public ActionResult Register()
        {
            return View();
        }

        /// <summary>
        /// 发送注册验证码
        /// </summary>
        /// <param name="email"></param>
        /// <param name="password"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        [HttpPost, ExcUserAuth]
        public ActionResult SendRegisterCode(string email)
        {
            #region MyRegion
            try
            {
                if (string.IsNullOrEmpty(email))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("注册邮箱为空.");
                }
                if (!EmailHelper.IsEmail(email.Trim()))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("邮箱格式不正确.");
                }
                if (UsersBLL.Instance.IsExists(email.Trim()))
                {
                    srm.code = ErrorCode.EmaiRegisted.ToInt();
                    throw new InvalidOperationException("该邮箱已被注册.");
                }
                if (!EmailBLL.Instance.CheckSendNum(email.Trim()))
                {
                    srm.code = ErrorCode.EmaiRegisted.ToInt();
                    throw new InvalidOperationException("同一邮箱24小时最多发3次.");
                }
                if (!EmailBLL.Instance.CheckSendTime(email.Trim()))
                {
                    srm.code = ErrorCode.EmaiRegisted.ToInt();
                    throw new InvalidOperationException("发送时间须间隔60秒.");
                }
                //生成验证码
                var code = Guid.NewGuid().ToString("N").Substring(5, 6);
                Task.Factory.StartNew(() =>
                {
                    EmailHelper.SMTPSend(email.Trim(), "[MPic图床小助手]注册验证", EmailHelper.EmailTemplate().Replace("{验证码}", code));
                    //EmailHelper.SendEmail(email.Trim(), "[MPic图床小助手]注册验证", EmailHelper.EmailTemplate().Replace("{验证码}", code));
                });
                //发送邮件
                EmailBLL.Instance.Send(-1, email.Trim(), code.Trim());

                srm.msg = "恭喜你，验证码发送成功.";
            }
            catch (InvalidOperationException e)
            {
                srm.msg = e.Message;
            }
            catch (Exception e)
            {
                srm.code = ErrorCode.BusySystem.ToInt();
                srm.msg = ErrorCode.BusySystem.Description();
                LoggerHelper.Log("【Main】->【SendRegisterCode】", e);
            }
            return Result(srm);
            #endregion
        }


        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="email">邮箱</param>
        /// <param name="password">密码</param>
        /// <param name="code">验证码</param>
        /// <returns></returns>
        [HttpPost, ExcUserAuth]
        public ActionResult Register(string email, string password, string code)
        {
            #region MyRegion
            try
            {
                if (string.IsNullOrEmpty(email))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("注册邮箱为空.");
                }
                if (string.IsNullOrEmpty(password))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("注册密码为空.");
                }
                if (string.IsNullOrEmpty(code))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("验证码为空.");
                }
                if (!EmailHelper.IsEmail(email.Trim()))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("邮箱格式不正确.");
                }
                //TODO:检查验证码
                if (!EmailBLL.Instance.CheckVarifyCode(email.Trim(), code.Trim()))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("验证码有误.");
                }
                if (UsersBLL.Instance.IsExists(email.Trim()))
                {
                    srm.code = ErrorCode.EmaiRegisted.ToInt();
                    throw new InvalidOperationException("该邮箱已被注册.");
                }
                //注册
                var result = UsersBLL.Instance.Register(email.Trim(), EncryptHelper.MD5(password.Trim()));
                if (!result)
                {
                    srm.code = ErrorCode.RegisterFail.ToInt();
                    throw new InvalidOperationException(ErrorCode.RegisterFail.Description());
                }
                srm.msg = "恭喜你，注册成功,页面跳转中.";
            }
            catch (InvalidOperationException e)
            {
                srm.msg = e.Message;
            }
            catch (Exception e)
            {
                srm.code = ErrorCode.BusySystem.ToInt();
                srm.msg = ErrorCode.BusySystem.Description();
                LoggerHelper.Log("【Main】->【Register】", e);
            }
            return Result(srm);
            #endregion
        }

        #region 设置
        /// <summary>
        /// 设置
        /// </summary>
        /// <returns></returns>
        public ActionResult Setting()
        {
            var currUser = new CurrentUser();
            var user = UsersBLL.Instance.GetUser(currUser.UserName);
            var qiniu = QiNiuBLL.Instance.GetByUserId(currUser.UserId);
            if (qiniu == null)
            {
                qiniu = new QiNiuEntity();
            }
            var oss = AliYunOSSBLL.Instance.GetByUserId(currUser.UserId);
            if (oss == null)
            {
                oss = new AliYunOSSEntity();
            }
            ViewBag.QiNiu = qiniu;
            ViewBag.AliYunOss = oss;
            ViewBag.DefaultUploadType = user.DefaultUploadType;
            return View();
        }

        /// <summary>
        /// 设置七牛信息
        /// </summary>
        /// <param name="qiniuId"></param>
        /// <param name="bucket"></param>
        /// <param name="accessKey"></param>
        /// <param name="secretKey"></param>
        /// <param name="domain"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult QiNiu(int qiniuId, string bucket, string accessKey, string secretKey, string domain)
        {
            #region MyRegion
            try
            {
                if (string.IsNullOrEmpty(bucket))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("空间名称为空.");
                }
                if (string.IsNullOrEmpty(accessKey))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("AccessKey为空.");
                }
                if (string.IsNullOrEmpty(secretKey))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("SecretKey为空.");
                }
                if (string.IsNullOrEmpty(domain))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("空间域名为空.");
                }
                if (!StrHelper.IsUrl(domain.Trim()))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("域名格式有误，必须以http(s)开头.");
                }
                var userId = new CurrentUser().UserId;
                var result = false;
                //新增
                if (qiniuId < 1)
                {
                    result = QiNiuBLL.Instance.Insert(userId, bucket.Trim(), accessKey.Trim(), secretKey.Trim(), domain.Trim());
                }
                else
                {
                    var qiniu = QiNiuBLL.Instance.GetById(qiniuId);
                    if (qiniu == null)
                    {
                        srm.code = ErrorCode.SettingFail.ToInt();
                        throw new InvalidOperationException(ErrorCode.SettingFail.Description());
                    }
                    qiniu.Bucket = bucket.Trim();
                    qiniu.AccessKey = accessKey.Trim();
                    qiniu.SecretKey = secretKey.Trim();
                    qiniu.DomainName = domain.Trim();
                    result = QiNiuBLL.Instance.Update(qiniu);
                }
                if (!result)
                {
                    srm.code = ErrorCode.SettingFail.ToInt();
                    throw new InvalidOperationException(ErrorCode.SettingFail.Description());
                }
                UsersBLL.Instance.Update(userId, UploadTypeEnum.QiNiu.ToInt(), null);
                srm.msg = "恭喜你，信息保存成功";
            }
            catch (InvalidOperationException e)
            {
                srm.msg = e.Message;
            }
            catch (Exception e)
            {
                srm.code = ErrorCode.BusySystem.ToInt();
                srm.msg = ErrorCode.BusySystem.Description();
                LoggerHelper.Log("【Main】->【QiNiu】", e);
            }
            return Result(srm);
            #endregion
        }

        /// <summary>
        /// 设置阿里云OSS信息
        /// </summary>
        /// <param name="ossId"></param>
        /// <param name="bucket"></param>
        /// <param name="endpoint"></param>
        /// <param name="accessKey"></param>
        /// <param name="secretKey"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult AliYun(int ossId, string bucket, string endpoint, string accessKey, string secretKey)
        {
            #region MyRegion
            try
            {
                if (string.IsNullOrEmpty(bucket))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("Bucket为空.");
                }
                if (string.IsNullOrEmpty(endpoint))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("Endpoint为空.");
                }
                if (string.IsNullOrEmpty(accessKey))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("AccessKey为空.");
                }
                if (string.IsNullOrEmpty(secretKey))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("SecretKey为空.");
                }
                var userId = new CurrentUser().UserId;
                var result = false;
                //新增
                if (ossId < 1)
                {
                    result = AliYunOSSBLL.Instance.Insert(userId, bucket.Trim(), endpoint.Trim(), accessKey.Trim(), secretKey.Trim());
                }
                else
                {
                    var oss = AliYunOSSBLL.Instance.GetById(ossId);
                    if (oss == null)
                    {
                        srm.code = ErrorCode.SettingFail.ToInt();
                        throw new InvalidOperationException(ErrorCode.SettingFail.Description());
                    }
                    oss.Bucket = bucket.Trim();
                    oss.AccessKey = accessKey.Trim();
                    oss.SecretKey = secretKey.Trim();
                    oss.Endpoint = endpoint.Trim();
                    result = AliYunOSSBLL.Instance.Update(oss);
                }
                if (!result)
                {
                    srm.code = ErrorCode.SettingFail.ToInt();
                    throw new InvalidOperationException(ErrorCode.SettingFail.Description());
                }
                UsersBLL.Instance.Update(userId, UploadTypeEnum.AliYun.ToInt(), null);
                srm.msg = "恭喜你，信息保存成功";
            }
            catch (InvalidOperationException e)
            {
                srm.msg = e.Message;
            }
            catch (Exception e)
            {
                srm.code = ErrorCode.BusySystem.ToInt();
                srm.msg = ErrorCode.BusySystem.Description();
                LoggerHelper.Log("【Main】->【AliYun】", e);
            }
            return Result(srm);
            #endregion
        }
        #endregion

        /// <summary>
        /// 我的相册
        /// </summary>
        /// <returns></returns>
        public ActionResult MyAlbum()
        {
            return View();
        }

        /// <summary>
        /// 我的所有相册
        /// </summary>
        /// <returns></returns>
        [HttpGet, ExcUserAuth]
        public ActionResult Albums()
        {
            #region MyRegion
            try
            {
                var userId = 0;
                object result = new List<UserAlbumEntity> { new UserAlbumEntity { AlbumId = 0, AlbumName = "默认相册" } };
                if (User.Identity.IsAuthenticated)
                {
                    userId = new CurrentUser().UserId;
                    //获取相册
                    var list = UserAlbumBLL.Instance.Get(userId);
                    result = list.Select(x => new
                    {
                        x.AlbumId,
                        x.AlbumName,
                        x.FilesNumber,
                        CreateTime = x.CreateTime.ToString("yyyy-MM-dd")
                    });
                }
                srm.data = result;
            }
            catch (InvalidOperationException e)
            {
                srm.msg = e.Message;
            }
            catch (Exception e)
            {
                srm.code = ErrorCode.BusySystem.ToInt();
                srm.msg = ErrorCode.BusySystem.Description();
                LoggerHelper.Log("【Main】->【Albums】", e);
            }
            return Result(srm);
            #endregion
        }

        /// <summary>
        /// 我的上传文件
        /// </summary>
        /// <returns></returns>
        public ActionResult Files(int albumId)
        {
            ViewBag.AlbumId = albumId;
            return View();
        }

        /// <summary>
        /// 我的上传文件
        /// </summary>
        /// <param name="albumId"></param>
        /// <returns></returns>
        [HttpGet]
        public ActionResult MyFiles(int albumId)
        {
            try
            {
                var list = FilesBLL.Instance.List(new CurrentUser().UserId, albumId);
                var result = list.Select(x => new
                {
                    x.FileId,
                    x.FileKey,
                    x.FileUrl,
                    UploadDate = x.UploadDate.ToString("yyyy-MM-dd HH:mm:ss")
                });
                srm.data = result;
            }
            catch (InvalidOperationException e)
            {
                srm.msg = e.Message;
            }
            catch (Exception e)
            {
                srm.code = ErrorCode.BusySystem.ToInt();
                srm.msg = ErrorCode.BusySystem.Description();
                LoggerHelper.Log("【Main】->【MyFiles】", e);
            }
            return Result(srm);
        }

        /// <summary>
        /// 我的账号
        /// </summary>
        /// <returns></returns>
        public ActionResult MyAccount()
        {
            return View();
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult SetPassword(string oldPassword, string newPassword, string confirmPassword)
        {
            try
            {
                if (string.IsNullOrEmpty(oldPassword))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("原密码为空.");
                }
                if (string.IsNullOrEmpty(newPassword))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("新密码为空.");
                }
                if (string.IsNullOrEmpty(confirmPassword))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("确认密码为空.");
                }
                if (!newPassword.Equals(confirmPassword))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("两次密码不一致.");
                }
                var user = UsersBLL.Instance.GetUser(new CurrentUser().UserName);
                if (!user.Password.Equals(EncryptHelper.MD5(oldPassword.Trim())))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("原密码有误.");
                }
                if (user.Password.Equals(EncryptHelper.MD5(newPassword.Trim())))
                {
                    srm.code = ErrorCode.ParameterError.ToInt();
                    throw new InvalidOperationException("新密码不能与原密码一样.");
                }
                var result = UsersBLL.Instance.Update(user.UserId, EncryptHelper.MD5(newPassword.Trim()));
                if (!result)
                {
                    srm.code = ErrorCode.SetPasswordFail.ToInt();
                    throw new InvalidOperationException("修改密码失败.");
                }
                srm.msg = "修改成功.";
            }
            catch (InvalidOperationException e)
            {
                srm.msg = e.Message;
            }
            catch (Exception e)
            {
                srm.code = ErrorCode.BusySystem.ToInt();
                srm.msg = ErrorCode.BusySystem.Description();
                LoggerHelper.Log("【Main】->【SetPassword】", e);
            }
            return Result(srm);
        }

        /// <summary>
        /// 退登
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult Logout()
        {
            #region MyRegion
            try
            {
                bool logged = User.Identity.IsAuthenticated;
                if (!logged)
                {
                    srm.code = (int)ErrorCode.LogoutFail.ToInt();
                    throw new InvalidOperationException("未登录，不需要退出");
                }
                FormsAuthentication.SignOut();
                if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
                {
                    Request.Cookies[FormsAuthentication.FormsCookieName].Expires = DateTime.Now.AddDays(-1);
                    this.Response.Cookies.Add(Request.Cookies[FormsAuthentication.FormsCookieName]);
                }
                Request.Cookies.Clear();
                Session.Clear();
            }
            catch (InvalidOperationException e)
            {
                srm.msg = e.Message;
            }
            catch (Exception e)
            {
                srm.code = ErrorCode.BusySystem.ToInt();
                srm.msg = ErrorCode.BusySystem.Description();
                LoggerHelper.Log("【Main】->【Logout】", e);
            }
            return Result(srm);
            #endregion
        }
    }
}